package com.tcm.common.Interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.tcm.common.enums.CachePrefix;
import com.tcm.common.enums.ResponseEnum;
import com.tcm.entity.bo.UserCacheBo;
import com.tcm.entity.resp.R;
import com.tcm.utils.AccessTokenUtil;
import com.tcm.utils.RedisUtil;
import io.micrometer.core.lang.NonNullApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 权限验证拦截器（已纳入Spring IoC容器管理）
 * @author Guqier
 */
@NonNullApi
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 获取accessToken
        String accessToken = AccessTokenUtil.getAccessToken(request);

        // JSON 转换对象
        ObjectMapper objectMapper = new ObjectMapper();

        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        // 如果没有accessToken信息，同样不予放行
        if (!StringUtils.hasText(accessToken)) {
            response.getWriter().print(objectMapper.writeValueAsString(R.fail(ResponseEnum.USER_NOT_LOGIN))); //没有accessToken信息
            return false;
        }

        // 校验AccessToken
        boolean res = AccessTokenUtil.verifyAccessToken(accessToken);
        if (res){
            // 校验缓存中的登录信息
            Long userId = AccessTokenUtil.getUserId(accessToken);
            UserCacheBo userCacheBo = redisUtil.getCacheObject(CachePrefix.PC_USER_TOKEN.getCacheKey(String.valueOf(userId)));
            if (!accessToken.equals(userCacheBo != null ? userCacheBo.getToken() : null)) {
                // 查询延迟校验是否存在
                String oldToken = redisUtil.getCacheObject(CachePrefix.PC_TOKEN_DELAYED_FILTERING.getCacheKey(String.valueOf(userId)));
                if (accessToken.equals(oldToken)){
                    return true;
                }
                response.getWriter().write(objectMapper.writeValueAsString(R.fail(ResponseEnum.TOKEN_EXPIRED)));
                return false;
            }
            return true;  //请求放行
        }else {
            // 拦截请求并返回错误信息
            response.getWriter().print(objectMapper.writeValueAsString(R.fail(ResponseEnum.INVALID_TOKEN))); //accessToken无效
            return false;
        }
    }
}
